package utils

import (
	"errors"
	"github.com/golang-jwt/jwt/v5"
	"github.com/spf13/viper"
	"strconv"
	"time"
)

type Claims struct {
	Username string
	UserId   uint
	RoleKeys []string `json:"role_keys"`
	jwt.RegisteredClaims
}

var key = viper.GetString("jwt.key")

// GenerateToken 生成JWT令牌
// 参数:
//
//	loginName: 用户登录名
//	userID: 用户ID
//	roleIds: 用户角色ID列表
//	expDuration: 令牌有效期时长
//
// 返回值:
//
//	string: 生成的JWT令牌字符串
//	error: 错误信息，如果生成令牌失败
func GenerateToken(username string, userID uint, roleKeys []string, expDuration time.Duration) (string, error) {
	// 初始化Claims结构体，包含用户信息和令牌的注册声明
	c := Claims{
		Username: username,
		UserId:   userID,
		RoleKeys: roleKeys,
		RegisteredClaims: jwt.RegisteredClaims{
			Issuer:    "Pure_admin_server",                                                                    // 令牌发行者
			Subject:   "tang",                                                                                 // 令牌主题
			Audience:  jwt.ClaimStrings{"Android_APP", "IOS_APP", "WEB"},                                      // 令牌受众
			ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Minute * viper.GetDuration("jwt.tokenExpire"))), // 令牌过期时间
			IssuedAt:  jwt.NewNumericDate(time.Now()),                                                         // 令牌发行时间
			ID:        username + strconv.FormatInt(time.Now().UnixNano(), 10),                                // 令牌唯一标识符
		},
	}
	// 使用HS256算法创建并签署JWT令牌
	return jwt.NewWithClaims(jwt.SigningMethodHS256, c).SignedString([]byte(key))
}

// ParseTokenHs256 解密token
func ParseTokenHs256(tokenString string) (*Claims, error) {
	//解析token字符串，并使用自定义的Myclaims类型进行验证
	token, err := jwt.ParseWithClaims(tokenString, &Claims{}, func(token *jwt.Token) (interface{}, error) {
		return []byte(key), nil //返回签名密钥
	})
	if err != nil {
		return nil, err
	}

	//检查token是否有效
	if !token.Valid {
		return nil, errors.New("身份验证失败,token无效")
	}

	//断言成为Myclaims类型
	claims, ok := token.Claims.(*Claims)
	if !ok {
		return nil, errors.New("无效的token类型")
	}
	return claims, nil
}
func ParseRefreshToken(tokenString string) (*Claims, error) {
	claims, err := ParseTokenHs256(tokenString)
	if err != nil {
		return nil, errors.New("无效的 Refresh Token")
	}
	// 可选：检查是否在黑名单中，或是否被吊销
	return claims, nil
}
